package com.fz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fz.entity.*;
import com.fz.mapper.OrdersMapper;
import com.fz.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fz.util.FzUtil;
import com.fz.vo.GoodsVo;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 存储订单信息 服务实现类
 * </p>
 *
 * @author hyr
 * @since 2025-06-18
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService
{
    //    @Resource
//    OrdersMapper ordersMapper;
    @Resource
    UserService tUserService;
    @Resource
    PasswordEncoder passwordEncoder;
    @Resource
    GoodsService goodsService;
    @Resource
    OrderGoodsService orderGoodsService;

    @Resource
    CouponService couponService;

    public List<GoodsVo> getByOrdersId(Long orderId) {
        List<GoodsVo> goodsVoList = baseMapper.getByOrderId(orderId);
        for (GoodsVo goodsVo : goodsVoList) {
            if (null != goodsVo.getImgs()){
                goodsVo.setImagePathList(goodsVo.getImgs().split(";"));
            }
            if (null != goodsVo.getCount() && null != goodsVo.getPrice()) {
                Long count = Long.valueOf(goodsVo.getCount());
                BigDecimal decimalCount = BigDecimal.valueOf(count);
                BigDecimal totalAmount = goodsVo.getPrice().multiply(decimalCount);
                goodsVo.setTotalAmount(totalAmount);
            }
        }
        return goodsVoList;
    }

    public void setGoodsList(Page<Orders> ordersPage) {
        List<Orders> ordersList = ordersPage.getRecords();
        for (Orders orders : ordersList) {
            List<GoodsVo> goodsVoList = getByOrdersId(orders.getId());
            orders.setGoodsList(goodsVoList);
        }
        ordersPage.setRecords(ordersList);
    }


    @Override
    public Page<Orders> getList(Long userId, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        wrapper.eq("is_deleted", 0);
        Page<Orders> ordersPage;
        if(userId == -1) {
            ordersPage = this.page(new Page<>(pageNo, pageSize), wrapper);
            setGoodsList(ordersPage);
        }else {
            wrapper.eq("user_id", userId);
            ordersPage = this.page(new Page<>(pageNo, pageSize), wrapper);
            setGoodsList(ordersPage);

        }
        return ordersPage;
    }

    @Override
    public Page<Orders> searchByOrderId(Long userId, Integer pageNo, Integer pageSize, String searchVal) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.like("order_id", searchVal);
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        wrapper.eq("is_deleted", 0);
        Page<Orders> ordersPage = this.page(new Page<>(pageNo, pageSize),wrapper);
        setGoodsList(ordersPage);
        return ordersPage;
    }

    @Override
    public Page<Orders> getByOrderStatus(Long userId, String status, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        wrapper.eq("order_status",status);
        wrapper.eq("is_deleted", 0);
        Page<Orders> ordersPage = this.page(new Page<>(pageNo,pageSize),wrapper);
        setGoodsList(ordersPage);
        return ordersPage;
    }

    @Override
    public Page<Orders> getByTimeRange(Long userId, String maxTime, String minTime, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        LocalDateTime min = null;
        LocalDateTime max = null;
        if(!maxTime.isEmpty() && !minTime.isEmpty()) {
            min = LocalDateTime.parse(minTime);
            max = LocalDateTime.parse(maxTime);
            System.out.println(min);
            System.out.println(max);
            wrapper.between("create_time", minTime, maxTime);
        }
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        wrapper.eq("is_deleted", 0);
        Page<Orders> ordersPage = this.page(new Page<>(pageNo, pageSize),wrapper);
        setGoodsList((ordersPage));
        return ordersPage;
    }

    @Override
    @Transactional
    public Long createOrder(Long userId, BigDecimal totalAmount, Long[] goodsIds, Integer[] counts, Long storeId) {
        boolean flag = true;
        String orderCode = FzUtil.randomOrderCode("OR");
        Orders orders = new Orders(
                orderCode,
                userId,
                totalAmount,
                "余额支付",
                "自提",
                "未付款",
                LocalDateTime.now());
        if (!this.save(orders)) {
            throw new RuntimeException("系统异常");
        }

        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderCode);
        Orders one = this.getOne(wrapper);
        for (int i = 0; i < goodsIds.length; i++) {
            System.out.println(i);
            if(!orderGoodsService.save(new OrderGoods(one.getId(), goodsIds[i], storeId, counts[i]))) {
                throw new RuntimeException("系统异常");
            }
        }
        return one.getId();
    }

    @Override
    public Orders getById(Long id) {
        Orders orders = super.getById(id);
        orders.setGoodsList(getByOrdersId(orders.getId()));
        return orders;
    }

   // @Override
//    public Boolean payTheOrder(String password, Long orderId, Long userId, Long couponId) {
//        Orders orderInfo = getById(orderId);
//        User user = tUserService.getById(userId);
//
//        // 密码正确
//        if(passwordEncoder.matches(password, user.getPassword())) {
//            Coupon coupon = couponService.getById(couponId);
//            if (coupon.getUserId() == userId) {
//                // 扣钱
//                MathContext mathContext = MathContext.DECIMAL32;
//                BigDecimal result = user.getAccount()
//                        .subtract(orderInfo.getTotalAmount()
//                                .subtract(BigDecimal.valueOf(coupon.getAmount())) , mathContext);
//                coupon.setIsStatus(1);
//                couponService.save(coupon);
////            System.out.println("用户余额"+user.getAccount());
////            System.out.println("结果"+result);
//                user.setAccount(result);
//                tUserService.updateById(user);
//                // 订单状态更新
//                orderInfo.setOrderStatus("已付款");
//                orderInfo.setUpdateTime(LocalDateTime.now());
//                this.updateById(orderInfo);
//                // 商品相关修改
//                List<GoodsVo> goodsList = orderInfo.getGoodsList();
//                for (GoodsVo goodsVo : goodsList) {
//                    Goods goods = goodsService.getById(goodsVo.getId());
//                    goods.setSales(goods.getSales() + goodsVo.getCount());
//                    goods.setStore(goods.getStore() - goodsVo.getCount());
//                    goodsService.updateById(goods);
//                }
//            }
//
//        } else {
//            return false;
//        }
//        return true;
//    }
   @Override
   public Boolean payTheOrder(String password, Long orderId, Long userId, Long couponId) {
       Orders orderInfo = getById(orderId);
       User user = tUserService.getById(userId);

       // 密码正确
       if(passwordEncoder.matches(password, user.getPassword())) {
           // 如果传入了优惠券ID，使用已有的优惠券
           if (couponId != null && couponId > 0) {
               Coupon coupon = couponService.getById(couponId);
               if (coupon != null && coupon.getUserId().equals(userId)) {
                   // 扣钱
                   MathContext mathContext = MathContext.DECIMAL32;
                   BigDecimal result = user.getAccount()
                           .subtract(orderInfo.getTotalAmount()
                                   .subtract(BigDecimal.valueOf(coupon.getAmount()) , mathContext));
                   coupon.setIsStatus(1); // 标记为已使用
                   couponService.saveOrUpdate(coupon); // 使用saveOrUpdate而不是save

                   user.setAccount(result);
                   tUserService.updateById(user);

                   // 订单状态更新
                   orderInfo.setOrderStatus("已付款");
                   orderInfo.setUpdateTime(LocalDateTime.now());
                   this.updateById(orderInfo);

                   // 商品相关修改
                   List<GoodsVo> goodsList = orderInfo.getGoodsList();
                   for (GoodsVo goodsVo : goodsList) {
                       Goods goods = goodsService.getById(goodsVo.getId());
                       goods.setSales(goods.getSales() + goodsVo.getCount());
                       goods.setStore(goods.getStore() - goodsVo.getCount());
                       goodsService.updateById(goods);
                   }
                   return true;
               }
           } else {
               // 没有使用优惠券，直接支付
               user.setAccount(user.getAccount().subtract(orderInfo.getTotalAmount()));
               tUserService.updateById(user);

               orderInfo.setOrderStatus("已付款");
               orderInfo.setUpdateTime(LocalDateTime.now());
               this.updateById(orderInfo);

               return true;
           }
       }
       return false;
   }

    @Override
    @Transactional
    public Boolean batchShipOrder(Long[] ids, String orderStatus) {
        for (Long id : ids) {
            if (!this.updateById(new Orders(id,orderStatus))){
                throw new RuntimeException("发货失败");
            }
        }
        return true;
    }

    @Override
    public Boolean deleteOrderByIdLogically(Long orderId) {
        Orders orders = new Orders();
        orders.setIsDeleted(1);
        orders.setId(orderId);
        return updateById(orders);
    }

}
